home *** CD-ROM | disk | FTP | other *** search
- page 75, 110
-
- ;--------------------------------------------------------------------
- ;
- ; SYSID.ASM
- ;
- ; Version 4.7
- ;
- ; Two subprograms used by SYSID.PAS:
- ;
- ; CPUID - identifies host CPU and NDP (if
- ; any)
- ; DISKREAD - reads absolute sectors from disk
- ;
- ; Steve Grant
- ; Long Beach, CA
- ; July 31, 1989
- ;
- ;--------------------------------------------------------------------
-
- .8086
- .8087
-
- public CPUID, DISKREAD
-
- CODE segment byte
-
- ;--------------------------------------------------------------------
-
- CPUID proc near
-
- assume cs:CODE, ds:DATA, es:nothing, ss:nothing
-
- ; On entry:
- ;
- ; BP
- ; SP => near return address
- ; offset of a cpu_info_t record
- ; segment " " " "
- ;
- ; On exit, the cpu_info_t record has been filled in as follows:
- ;
- ; byte = CPU type
- ; word = Machine Status Word
- ; 6 bytes = Global Descriptor Table
- ; 6 bytes = Interrupt Descriptor Table
- ; boolean = segment register change/interrupt flag
- ; boolean = 80386 multiplication bug flag
- ; byte = NDP type
- ; word = NDP control word
-
- mCPU equ byte ptr [bx]
- mMSW equ [bx + 1]
- mGDT equ [bx + 3]
- mIDT equ [bx + 9]
- mopsize equ byte ptr [bx + 15]
- mchkint equ byte ptr [bx + 16]
- mmult equ byte ptr [bx + 17]
- mNDP equ byte ptr [bx + 18]
- mNDPCW equ [bx + 19]
-
- f8088 equ 0
- f8086 equ 1
- fV20 equ 2
- fV30 equ 3
- f80188 equ 4
- f80186 equ 5
- f80286 equ 6
- f80386 equ 7
- funk = 0FFH
-
- false equ 0
- true equ 1
-
- push bp
- mov bp, sp
- push ds
- lds bx, [bp + 4]
- call cpu
- call chkint
- call ndp
- pop ds
- pop bp
- ret 4
-
- ;--------------------------------------------------------------------
-
- cpu proc near
-
- ; interrupt of multi-prefix string instruction
-
- sti
- mov cx, 0FFFFH
- rep lods byte ptr es : [si]
- jcxz cpu_03
-
- call piq
- cmp dx, 4
- jne cpu_01
-
- mov mCPU, f8088
- ret
-
- cpu_01:
- cmp dx, 6
- je cpu_02
-
- jmp cpu_12
-
- cpu_02:
- mov mCPU, f8086
- ret
-
- cpu_03:
-
- ; number of bits in displacement register used by shift
-
- mov al, 0FFH
- mov cl, 20H
- shl al, cl
- or al, al
- jnz cpu_05
-
- call piq
- cmp dx, 4
- jne cpu_04
-
- mov mCPU, fV20
- ret
-
- cpu_04:
- cmp dx, 6
- jne cpu_12
-
- mov mCPU, fV30
- ret
-
- cpu_05:
-
- ; order of write/decrement by PUSH SP
-
- push sp
- pop ax
- cmp ax, sp
- je cpu_07
-
- call piq
- cmp dx, 4
- jne cpu_06
-
- mov mCPU, f80188
- ret
-
- cpu_06:
- cmp dx, 6
- jne cpu_12
-
- mov mCPU, f80186
- ret
-
- cpu_07:
-
- .286P
-
- smsw mMSW
- sgdt mGDT
- sidt mIDT
-
- .8086
-
- ; try to alter flag register bits 15-12
-
- pushf
- pop ax
- mov cx, ax
- xor cx, 0F000H
- push cx
- popf
- pushf
- pop cx
- cmp ax, cx
- jne cpu_08
-
- mov mCPU, f80286
- ret
-
- cpu_08:
- mov mCPU, f80386
- pushf
- mov ax, sp
- popf
- inc ax
- inc ax
- cmp ax, sp
- jnz cpu_09
-
- mov mopsize, false
- jmp short cpu_10
-
- cpu_09:
- mov mopsize, true
-
- cpu_10:
-
- .386P
-
- mov eax, 0417A000H
- mov ecx, 81H
- mul ecx
- cmp edx, 2
- jne short cpu_11
-
- cmp eax, 0FE7A000H
- jne short cpu_11
-
- mov mmult, true
- ret
-
- cpu_11:
- mov mmult, false
- ret
-
- ; BIX ibm.at/hardware #4663
-
- .8086
-
- cpu_12:
- mov mCPU, funk
- ret
-
- cpu endp
-
- ;--------------------------------------------------------------------
-
- piq proc near
-
- ; On exit:
- ;
- ; DX = length of prefetch instruction queue
- ;
- ; This subroutine uses self-modifying code but can nevertheless
- ; be run repeatedly in the course of the calling program.
-
- count = 7
- opincdx equ 42H ; inc dx opcode
- opnop equ 90H ; nop opcode
-
- mov al, opincdx
- mov cx, count
- push cx
- push cs
- pop es
- mov di, offset piq_01 - 1
- push di
- std
- rep stosb
- mov al, opnop
- pop di
- pop cx
- xor dx, dx
- cli
- rep stosb
- rept count
- inc dx
- endm
-
- piq_01:
- sti
- ret
-
- piq endp
-
- ;--------------------------------------------------------------------
-
- chkint proc near
-
- ; save old INT 01H vector
-
- push bx
- mov ax, 3501H
- int 21H
- mov old_int01_ofs, bx
- mov old_int01_seg, es
- pop bx
-
- ; redirect INT 01H vector
-
- push ds
- mov ax, 2501H
- mov dx, seg new_int01
- mov ds, dx
- mov dx, offset new_int01
- int 21H
- pop ds
-
- ; set TF and change SS -- did we trap on following instruction?
-
- pushf
- pop ax
- or ah, 01H ; set TF
- push ax
- popf
- push ss ; CPU may wait one
- ; instruction before
- ; recognizing single step
- ; interrupt
- pop ss
-
- chkint_01: ; shouldn't ever trap here
-
- ; restore old INT 01H vector
-
- push ds
- mov ax, 2501H
- lds dx, old_int01
- int 21H
- pop ds
- ret
-
- ;--------------------------------------------------------------------
-
- new_int01:
-
- ; INT 01H handler (single step)
- ;
- ; On entry:
- ;
- ; SP => IP
- ; CS
- ; flags
-
- sti
- pop ax ; IP
- cmp ax, offset chkint_01
- jb new_int01_03
- je new_int01_01
- mov mchkint, true
- jmp short new_int01_02
-
- new_int01_01:
- mov mchkint, false
-
- new_int01_02:
- pop cx ; CS
- pop dx ; flags
- and dh, 0FEH ; turn off TF
- push dx ; flags
- push cx ; CS
-
- new_int01_03:
- push ax ; IP
- iret
-
- chkint endp
-
- ;--------------------------------------------------------------------
-
- ndp proc near
-
- fnone equ 0
- f8087 equ 1
- f80287 equ 2
- f80387 equ 3
- funk = 0FFH
-
- mov ndp_cw, 0000H
- cli
-
- ; The next three 80x87 instructions cannot carry the WAIT prefix,
- ; because there may not be an 80x87 for which to wait. The WAIT is
- ; therefore emulated with a MOV CX,<value>! LOOP $ combination.
-
- ; CPU NDP
- fnsave ndp_save ; 14 221
- mov cx, (221 - 23 + 16) / 17 + 1 ; 4
- loop $ ; 17*CX+5
- ; 17*CX+23
-
- fninit ; 8 8
- mov cx, (8 - 17 + 16) / 17 + 1 ; 4
- loop $ ; 17*CX+5
- ; 17*CX+17
-
- fnstcw ndp_cw ; 14 24
- mov cx, (24 - 23 + 16) / 17 + 1 ; 4
- loop $ ; 17*CX+5
- ; 17*CX+23
-
- sti
- mov ax, ndp_cw
- cmp ax, 0000H
- jne ndp_01
-
- mov mNDP, fnone
- ret
-
- ndp_01:
- cmp ax, 03FFH
- jne ndp_02
-
- mov mNDP, f8087
- jmp short ndp_04
-
- ndp_02:
- cmp ax, 037FH
- jne ndp_05
-
- fld1
- fldz
- fdiv
- fld1
- fchs
- fldz
- fdiv
- fcom
- fstsw ndp_sw
- mov ax, ndp_sw
- and ah, 41H ; C3, C0
- cmp ah, 40H ; ST(0) = ST(1)
- jne ndp_03
-
- mov mNDP, f80287
- jmp short ndp_04
-
- ndp_03:
- cmp ah, 01H ; ST(0) < ST(1)
- jne ndp_05
-
- mov mNDP, f80387
-
- ndp_04:
- frstor ndp_save
- fstcw mNDPCW
- ret
-
- ndp_05:
- mov mNDP, funk
- ret
-
- ndp endp
-
- CPUID endp
-
- ;--------------------------------------------------------------------
-
- DISKREAD proc near
-
- assume cs : CODE, ds : nothing, es : nothing
-
- ; On entry:
- ;
- ; BP
- ; SP => near return address
- ; offset of disk buffer
- ; segment " " "
- ; number of sectors to read
- ; starting logical sector number
- ; drive number (0=A, 1=B, etc.)
- ;
- ; On exit:
- ;
- ; AX = function result
- ; 00 - function successful
- ; 01..FF - DOS INT 25H error result
-
- drive equ [bp + 12]
- starting_sector equ [bp + 10]
- number_of_sectors equ [bp + 8]
- buffer equ [bp + 4]
-
- push bp
- mov bp, sp
- mov al, drive
- mov dx, starting_sector
- mov cx, number_of_sectors
- push ds
- lds bx, buffer
- int 25H
- inc sp ; fix broken stack
- inc sp
- pop ds
- jc diskread_01
-
- xor ax, ax
-
- diskread_01:
- pop bp
- ret 10
-
- DISKREAD endp
-
- CODE ends
-
- ;--------------------------------------------------------------------
-
- DATA segment byte
-
- ; storage for CPUID
-
- ; redirected INT 01H vector
-
- old_int01 label dword
- old_int01_ofs dw ?
- old_int01_seg dw ?
-
- ; storage for NDPID
-
- ; 80x87 control word after initialization, status word after divide by zero
-
- ndp_cw dw ?
- ndp_save db 94 dup (?)
- ndp_sw dw ?
-
- DATA ends
-
- end